<template>
  <div><button @click="handle">switch</button></div>
  <div class="warp">
    <div class="box" v-if="flag"></div>
    <!-- 利用name属性确定过度属性 duration 属性指定时长
    8个生命周期：
            @before-enter="beforeEnter（el:Element）" //对应enter-from
            @enter="enter（el:Element,done:Function）"//对应enter-active
            @after-enter="afterEnter（el:Element）"//对应enter-to
            @enter-cancelled="enterCancelled（el:Element）"//显示过度打断
            @before-leave="beforeLeave（el:Element）"//对应leave-from
            @leave="leave（el:Element）"//对应enter-active
            @after-leave="afterLeave（el:Element）"//对应leave-to
            @leave-cancelled="leaveCancelled（el:Element）"//离开过度打断-->
    <transition name="fade">
      <div class="box" v-if="flag"></div>
    </transition>
  </div>
  <hr />
  <div class="warp">
    <div class="box" v-if="flag"></div>
    <!-- 利用自定义类名确定过度属性 -->
    <transition
      enter-from-class="enter-from"
      enter-to-class="enter-to"
      enter-active-class="enter-active"
      leave-from-class="leave-from"
      leave-active-class="leave-active"
      leave-to-class="leave-to"
    >
      <div class="box" v-if="flag"></div>
    </transition>
  </div>
  <hr />
  <!-- 使用animate 动画库 npm i animate.css -S-->
  <div class="warp">
    <div class="box" v-if="flag"></div>
    <!-- 利用自定义类名确定过度属性 记得前缀-->
    <transition
      enter-active-class="animate__animated animate__rubberBand"
      leave-active-class="animate__animated animate__bounceOutDown"
    >
      <div class="box" v-if="flag"></div>
    </transition>
  </div>
  <hr />
  <div class="warp">
    <div class="box" v-if="flag"></div>
    <!-- 生命周期配合第三方库 gsap 实现炫酷效果  npm i gsap -S-->
    <transition @before-enter="enterFrom" @enter="enter" @leave="leave">
      <div class="box" v-if="flag"></div>
    </transition>
  </div>
  <hr />
  <div class="warp">
    <div class="box" v-if="flag"></div>
    <!-- appear 通过这个属性可以设置初始节点过度 就是页面加载完成就开始动画 对应三个状态
    首次加载使用-->
    <transition
      appear
      appear-active-class="appear-active"
      appear-from-class="appear-from"
      appear-to-class="appear-to"
    >
      <div class="box" v-if="flag"></div>
    </transition>
  </div>
</template>

<script lang="ts" setup>
import { ref } from "vue";
import "animate.css";
import gsap from "gsap";

let flag = ref(true);
const handle = () => {
  flag.value = !flag.value;
};
const enterFrom = (el: Element) => {
  gsap.set(el, {
    width: 0,
    height: 0,
  });
};
const enter = (el: Element, done: gsap.Callback) => {
  gsap.to(el, {
    width: 200,
    height: 200,
    onComplete: done,
  });
};
const leave = (el: Element, done: gsap.Callback) => {
  gsap.to(el, {
    width: 0,
    height: 0,
    onComplete: done,
  });
};
</script>

<style>
.box {
  width: 100px;
  height: 100px;
  background-color: red;
}
.warp {
  display: flex;
}
.fade-enter-from {
  width: 0;
  height: 0;
  transform: rotate(360deg);
}
.fade-enter-active {
  transition: all 5s linear;
}
.fade-enter-to {
  width: 100px;
  height: 100px;
}
.fade-leave-from {
  width: 100px;
  height: 100px;
  transform: rotate(360deg);
}
.fade-leave-active {
  transition: all 5s ease;
}
.fade-leave-to {
  width: 0;
  height: 0;
}

.enter-from {
  width: 0;
  height: 0;
  transform: rotate(360deg);
}
.enter-active {
  transition: all 5s linear;
}
.enter-to {
  width: 100px;
  height: 100px;
}
.leave-from {
  width: 100px;
  height: 100px;
  transform: rotate(360deg);
}
.leave-active {
  transition: all 5s ease;
}
.leave-to {
  width: 0;
  height: 0;
}
.appear-from {
  width: 0;
  height: 0;
}
.appear-active {
  transition: all 2s ease;
}
.appear-to {
  width: 200px;
  height: 200px;
}
</style>